package com.tanhua.dubbo.api.mongo;

import com.tanhua.domain.mongo.Friend;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.RecommendQuanzi;
import com.tanhua.domain.mongo.TimeLine;
import com.tanhua.domain.vo.MomentVo;
import com.tanhua.domain.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PublishApiImpl implements PublishApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 发布动态
     *
     * @param publish
     */
    @Override
    public void add(Publish publish) {

        //作者id等于登录用户id
        Long loginUserId = publish.getUserId();
        //1.生成动态的id
        ObjectId objectId = new ObjectId();
        publish.setId(objectId);
        //2.发布动态的时间
        long timeMillis = System.currentTimeMillis();
        publish.setCreated(timeMillis);

        //3.添加动态表
        mongoTemplate.insert(publish);
        //4.添加自己的时间线表记录
        TimeLine timeLine = new TimeLine(); // 时间线表
        timeLine.setCreated(timeMillis);
        timeLine.setUserId(loginUserId);
        timeLine.setPublishId(objectId); // 动态作者id

        //4.1，构建自己的时间线表名(数据库表名),后缀名加上自己的id
        String collectionName = "quanzi_time_line_" + loginUserId;
        //4.2，加进数据库
        mongoTemplate.insert(timeLine, collectionName);
        //5.查询好友
        //5.1/构建条件,用户id等于登录用户id
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(loginUserId));
        //得到登录用户的好友表数据集合
        List<Friend> friends = mongoTemplate.find(query, Friend.class);
        //6.遍历好友，添加记录到好友的时间线表
        if (!CollectionUtils.isEmpty(friends)) {

            for (Friend friend : friends) {
                timeLine = new TimeLine();
                timeLine.setCreated(timeMillis); //发布时间
                timeLine.setUserId(loginUserId); // 这条动态的作者id
                timeLine.setPublishId(objectId); //这个动态id（编号）

                //构建好友的集合名（表名）,后缀加上好友的id，
                String friendCollectionName = "quanzi_time_line_" + friend.getFriendId();

                //添加进数据库
                mongoTemplate.insert(timeLine, friendCollectionName);
            }
        }
    }

    /**
     * 查看好友动态
     *
     * @param page
     * @param pagesize
     * @param loginUserID 登录用户id
     * @return 返回 publish
     */
    @Override
    public PageResult findFriendPublishByTimeline(Long page, Long pagesize, Long loginUserID) {


        //1.查询登录用户自己的时间线表，分页查询
        //1.1构建条件，设置按创建的时间降序
        Query timeLineQuery = new Query();
        //1.2集合名称
        String timeLineCollectionName = "quanzi_time_line_" + loginUserID;
        //1.3统计总数
        long count = mongoTemplate.count(timeLineQuery, timeLineCollectionName);

        List<Publish> publishList = new ArrayList<>();
        if (count > 0) {  //1.4总数>0
            //设置按创建的时间降序
            timeLineQuery.with(Sort.by(Sort.Order.desc("created")));
            // 分页条件，
            timeLineQuery.skip((page - 1) * pagesize).limit(pagesize.intValue());
            //分页查询，p2:返回值的泛型类型
            List<TimeLine> timeLines = mongoTemplate.find(timeLineQuery, TimeLine.class, timeLineCollectionName);
            //2.把时间线表中的所有动态id取出来
            List<ObjectId> publishIds = timeLines.stream().map(TimeLine::getPublishId).collect(Collectors.toList());
            //3.查询动态表数据
            //3.1构建动态表的检查条件
            Query publishQuery = new Query();
            publishQuery.addCriteria(Criteria.where("id").in(publishIds));
            //3.2通过id批量查询动态数据
            publishList = mongoTemplate.find(publishQuery, Publish.class);
            //3.3按时间降序
            publishList.sort((publish1, publish2) -> publish2.getCreated().intValue() - publish1.getCreated().intValue());


        }
        //4.构建pageResult返回
        return PageResult.pageResult(page, pagesize, publishList, count);

    }

    /**
     * 查询推荐动态
     *
     * @param page
     * @param pagesize
     * @param loginUserID
     * @return
     */
    @Override
    public PageResult queryRecommendPublishList(Long page, Long pagesize, Long loginUserID) {

        //1.构建条件
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(loginUserID));
        //2.统计总数
        long count = mongoTemplate.count(query, RecommendQuanzi.class);
        //3.判断总集数是否有结果
        List<Publish> publishes = new ArrayList<>();
        if (count > 0) {
            //4.按时间降序排序,分页
            query.with(Sort.by(Sort.Order.desc("created")));
            query.skip((page - 1) * pagesize).limit(pagesize.intValue());
            //5.推荐动态集合
            List<RecommendQuanzi> recommendQuanzis = mongoTemplate.find(query, RecommendQuanzi.class);
            //6.取所有动态的id
            List<ObjectId> publishIds = recommendQuanzis.stream().map(RecommendQuanzi::getPublishId).collect(Collectors.toList());
            //7.构建动态查询条件，ids集合（获取所有动态）
            Query publishQuery = new Query(Criteria.where("id").in(publishIds));
            //8.批量动态查询
            publishes = mongoTemplate.find(publishQuery, Publish.class);

        }
        //9.构建返回的pageResult
        return PageResult.pageResult(page, pagesize, publishes, count);
    }

    /**
     * 查询某个用户的动态
     *
     * @param page
     * @param pagesize
     * @param targetUserId
     * @return
     */
    @Override
    public PageResult findMyPublishList(Long page, Long pagesize, Long targetUserId) {

        //1.查询登录用户自己的时间线表
        //1.1构建查询条件，设置按照创建的时间降序，作者是自己（登录用户）
        Query publishQuery = new Query(Criteria.where("userId").is(targetUserId));
        //1.2集合名称
        String timeLineCollectionName = "quanzi_time_line_" + targetUserId;
        //1.3统计个数
        long count = mongoTemplate.count(publishQuery, timeLineCollectionName);

        List<Publish> publishList = new ArrayList<>();
        //1.4总数大于0
        if (count > 0){
            //设置按照创建的时间降序
            publishQuery.with(Sort.by(Sort.Order.desc("created")));
            //分页
            publishQuery.skip((page-1)*pagesize).limit(pagesize.intValue());
            //p2：返回值的泛型类型 p3:查询哪张表
            List<TimeLine> timeLineList = mongoTemplate.find(publishQuery, TimeLine.class, timeLineCollectionName);
            //2.把时间线表中的所有动态id取出来
            List<ObjectId> publishIds = timeLineList.stream().map(TimeLine::getPublishId).collect(Collectors.toList());

            //3.查询动态表中的数据
            //3.1构建动态表的查询条件
            Query momentQuery = new Query();
            //3.2按时间降序
            momentQuery.with(Sort.by(Sort.Order.desc("created")));
            //3.3通过id批量查询
             publishList = mongoTemplate.find(momentQuery, Publish.class);
        }

        //构建pageResult返回
        return PageResult.pageResult(page,pagesize,publishList,count);

    }

    /**
     * 查询单条动态
     * @param publishId
     * @return
     */
    @Override
    public Publish findById(String publishId) {
       return mongoTemplate.findById(new ObjectId(publishId),Publish.class);
    }
}